package com.vehicle.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.vehicle.service.FaceRecognitionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * 人脸识别服务实现类
 * 集成百度云人脸识别API，提供人脸检测、搜索和注册功能
 */
@Service
public class FaceRecognitionServiceImpl implements FaceRecognitionService {

    private static final Logger logger = LoggerFactory.getLogger(FaceRecognitionServiceImpl.class);

    @Value("${baidu.app_id}")
    private String appId;

    @Value("${baidu.api_key}")
    private String apiKey;

    @Value("${baidu.secret_key}")
    private String secretKey;

    private static final String AUTH_TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";
    private static final String FACE_DETECT_URL = "https://aip.baidubce.com/rest/2.0/face/v3/detect";
    private static final String FACE_SEARCH_URL = "https://aip.baidubce.com/rest/2.0/face/v3/search";
    private static final String FACE_ADD_URL = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add";

    // 人脸库组ID
    private static final String GROUP_ID = "driver_face_group";

    private final HttpClient httpClient;

    public FaceRecognitionServiceImpl() {
        this.httpClient = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(30))
                .build();
    }

    /**
     * 获取百度云API授权token
     * @return token
     */
    @Override
    public String getAuthToken() {
        try {
            String url = AUTH_TOKEN_URL + "?grant_type=client_credentials&client_id=" + apiKey + "&client_secret=" + secretKey;
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(url))
                    .header("Content-Type", "application/json")
                    .timeout(Duration.ofSeconds(10))
                    .GET()
                    .build();

            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            JSONObject jsonObject = JSON.parseObject(response.body());

            if (jsonObject.containsKey("access_token")) {
                return jsonObject.getString("access_token");
            } else {
                logger.error("获取百度云token失败: {}", response.body());
                throw new RuntimeException("获取百度云token失败");
            }
        } catch (Exception e) {
            logger.error("获取百度云token异常", e);
            throw new RuntimeException("获取百度云token异常", e);
        }
    }

    /**
     * 人脸检测
     * @param file 人脸照片文件
     * @return 人脸token
     */
    @Override
    public String faceDetect(MultipartFile file) {
        try {
            // 1. 获取token
            String token = getAuthToken();

            // 2. 准备请求参数
            String base64Image = encodeImageToBase64(file);
            Map<String, Object> params = new HashMap<>();
            params.put("image", base64Image);
            params.put("image_type", "BASE64");
            params.put("face_field", "face_token,age,beauty,expression,faceshape,gender,glasses,landmark,race,quality,facetype");

            // 3. 发送请求
            String url = FACE_DETECT_URL + "?access_token=" + token;
            String responseBody = sendPostRequest(url, JSON.toJSONString(params));

            // 4. 解析响应
            JSONObject jsonObject = JSON.parseObject(responseBody);
            if (jsonObject.getIntValue("error_code") == 0) {
                JSONObject result = jsonObject.getJSONObject("result");
                if (result != null && result.containsKey("face_list")) {
                    // 假设只处理一张人脸
                    JSONObject face = result.getJSONArray("face_list").getJSONObject(0);
                    return face.getString("face_token");
                }
            } else {
                logger.error("人脸检测失败: {}", responseBody);
            }
            return null;
        } catch (Exception e) {
            logger.error("人脸检测异常", e);
            return null;
        }
    }

    /**
     * 人脸搜索
     * @param file 人脸照片文件
     * @return 搜索结果
     */
    @Override
    public String faceSearch(MultipartFile file) {
        try {
            // 1. 获取token
            String token = getAuthToken();

            // 2. 准备请求参数
            String base64Image = encodeImageToBase64(file);
            Map<String, Object> params = new HashMap<>();
            params.put("image", base64Image);
            params.put("image_type", "BASE64");
            params.put("group_id_list", GROUP_ID);
            params.put("quality_control", "NORMAL");
            params.put("liveness_control", "LOW");

            // 3. 发送请求
            String url = FACE_SEARCH_URL + "?access_token=" + token;
            String responseBody = sendPostRequest(url, JSON.toJSONString(params));

            // 4. 解析响应
            JSONObject jsonObject = JSON.parseObject(responseBody);
            if (jsonObject.getIntValue("error_code") == 0) {
                return responseBody;
            } else {
                logger.error("人脸搜索失败: {}", responseBody);
            }
            return null;
        } catch (Exception e) {
            logger.error("人脸搜索异常", e);
            return null;
        }
    }

    /**
     * 注册人脸到百度云人脸库
     * @param file 人脸照片文件
     * @param userId 用户ID
     * @param userName 用户名
     * @return 注册结果
     */
    @Override
    public boolean registerFaceToBaiDu(MultipartFile file, String userId, String userName) {
        try {
            // 1. 获取token
            String token = getAuthToken();

            // 2. 准备请求参数
            String base64Image = encodeImageToBase64(file);
            Map<String, Object> params = new HashMap<>();
            params.put("image", base64Image);
            params.put("image_type", "BASE64");
            params.put("group_id", GROUP_ID);
            params.put("user_id", userId);
            params.put("user_info", userName);
            params.put("quality_control", "NORMAL");
            params.put("liveness_control", "LOW");

            // 3. 发送请求
            String url = FACE_ADD_URL + "?access_token=" + token;
            String responseBody = sendPostRequest(url, JSON.toJSONString(params));

            // 4. 解析响应
            JSONObject jsonObject = JSON.parseObject(responseBody);
            if (jsonObject.getIntValue("error_code") == 0) {
                logger.info("人脸注册到百度云成功，用户ID: {}", userId);
                return true;
            } else {
                logger.error("人脸注册到百度云失败: {}", responseBody);
            }
            return false;
        } catch (Exception e) {
            logger.error("人脸注册到百度云异常", e);
            return false;
        }
    }

    /**
     * 发送POST请求
     * @param url 请求URL
     * @param body 请求体
     * @return 响应体
     */
    private String sendPostRequest(String url, String body) throws IOException, InterruptedException {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .timeout(Duration.ofSeconds(30))
                .POST(HttpRequest.BodyPublishers.ofString(body))
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    /**
     * 将图片文件编码为Base64
     * @param file 图片文件
     * @return Base64编码的图片字符串
     */
    private String encodeImageToBase64(MultipartFile file) throws IOException {
        byte[] bytes = file.getBytes();
        return Base64Utils.encodeToString(bytes);
    }
}